package com.example.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect // 这是一个切面
@Component
public class UserAspect {
    // 定义切点 (设置拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut(){
    }

    // 定义前置通知
    @Before("pointcut()")
    public void doBefore(){
        System.out.println("前置通知:执行");
    }

    // 定义后置通知
    @After("pointcut()")
    public void doAfter(){
        System.out.println("后置通知:执行");
    }

    // 返回后的通知
    @AfterReturning("pointcut()")
    public void doAfterRunning(){
        System.out.println("执行了AfterReturning");
    }

    // 环绕通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint point){
        // Spring 中的时间统计对象
        StopWatch stopWatch = new StopWatch();
        Object result = null;
        System.out.println("环绕通知执行前");
        try {
            stopWatch.start();
            result = point.proceed();
            stopWatch.stop();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        //System.out.println("环绕通知执行后");
        System.out.println(point.getSignature().getDeclaringTypeName()
                + "执行花费时间:" +
                stopWatch.getTotalTimeMillis() + "ms");
        return result;
    }

    // 报错后的通知
    @AfterThrowing("pointcut()")
    public void doAfterThrowing(){
        System.out.println("执行了AfterThrowing");
    }
}
